package com.springsecurity.demo.controller;

import com.springsecurity.demo.common.Response;
import com.springsecurity.demo.model.entity.SysUser;
import com.springsecurity.demo.model.entity.Users;
import com.springsecurity.demo.service.ISysMenuService;
import com.springsecurity.demo.service.ISysUserService;
import com.springsecurity.demo.service.IUsersService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;

@Api(description = "spring security demo", tags = {"spring security demo"})
@Controller
@RequestMapping("/spring_security_demo/")
public class HelloController {
    private static final Logger log = LoggerFactory.getLogger(HelloController.class);

    @Resource
    private IUsersService iUsersService;

    @Resource
    private ISysUserService iSysUserService;

    @Resource
    private ISysMenuService iSysMenuService;

    @ApiOperation(value = "hello", notes = "hello")
    @RequestMapping(value = "hello", method = RequestMethod.GET)
    @ResponseBody
    public Response<String> hello() {
        try {
            return Response.success("hello");
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test3", notes = "test3")
    @RequestMapping(value = "test3", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasAuthority('testAuthorization')")
    public Response<String> testAuthorization() {
        try {
            return Response.success("testAuthorization");
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test2", notes = "test2")
    @RequestMapping(value = "/test2", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasAuthority('dashboard:view')")
    public Response<List<String>> test2(@RequestParam Long userid) {
        try {
            List<String> menuInfoByOneUserId = iSysMenuService.getMenuInfoByOneUserId(userid);
            return Response.success(menuInfoByOneUserId);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test", notes = "test")
    @RequestMapping(value = "test", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasAnyAuthority('user:manage', 'settings:edit')")
    public Response<List<Users>> test(@RequestParam String username) {
        try {
            List<Users> userInfo = iUsersService.getUserInfo(username);
            return Response.success(userInfo);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test4", notes = "test4")
    @RequestMapping(value = "test4", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasRole('settings:edit')")
    /**
     * hasRole要求有对应的角色才可以访问，但是它内部会把我们传入的参数拼接上 ROLE_ 后再去比较。
     * 所以这种情况下要用用户对应的权限也要有 ROLE_ 这个前缀才可以。
     */
    public Response<List<Users>> test4(@RequestParam String username) {
        try {
            List<Users> userInfo = iUsersService.getUserInfo(username);
            return Response.success(userInfo);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test5", notes = "test5")
    @RequestMapping(value = "test5", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("hasAnyRole('user:manage', 'settings:edit')")
    /**
     * hasAnyRole 有任意的角色就可以访问。它内部也会把我们传入的参数拼接上 ROLE_ 后再去比较。
     * 所以这种情况下要用用户对应的权限也要有 ROLE_ 这个前缀才可以。
     */
    public Response<List<Users>> test5(@RequestParam String username) {
        try {
            List<Users> userInfo = iUsersService.getUserInfo(username);
            return Response.success(userInfo);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test6", notes = "test6")
    @RequestMapping(value = "test6", method = RequestMethod.GET)
    @ResponseBody
    @PreAuthorize("@dudu.hasAuthority('user:manage')")
    /**
     * 在SPEL表达式中使用 @dudu相当于获取容器中bean的名字为dudu的对象。然后再调用这个对象的hasAuthority方法
     */
    public Response<List<Users>> test6(@RequestParam String username) {
        try {
            List<Users> userInfo = iUsersService.getUserInfo(username);
            return Response.success(userInfo);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }

    @ApiOperation(value = "test7", notes = "test7")
    @RequestMapping(value = "test7", method = RequestMethod.GET)
    @ResponseBody
    public Response<List<Users>> test7(@RequestParam String username) {
        try {
            List<Users> userInfo = iUsersService.getUserInfo(username);
            return Response.success(userInfo);
        } catch (Exception e) {
            log.error("Error update status", e);
            return Response.failure("Failed to update status: " + e.getMessage());
        }
    }




}
